package com.ibeeking.found.upms.g.rest.service.impl;

import com.ibeeking.found.common.entity.CurrentUser;
import com.ibeeking.found.upms.g.rest.service.IGmcRoleService;
import com.ibeeking.found.upms.g.rest.service.IGmcUserRoleService;
import com.ibeeking.found.upms.service.common.bo.GmcUserRoleBO;
import com.ibeeking.found.upms.service.common.dos.UserRoleDO;
import com.ibeeking.found.upms.service.common.param.RoleUserParam;
import com.ibeeking.found.upms.service.common.param.UserRoleParam;
import com.ibeeking.found.upms.service.mapper.UserRoleMapper;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.json.JsonUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @project: GmcUserRoleServiceImpl
 * @description: 用户角色关系实现类
 * @Author ibeeking
 * @create: 2020-12-05 13:30:46
 **/
@Service
public class GmcUserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRoleDO> implements IGmcUserRoleService {

    @Resource
    private UserRoleMapper userRoleMapper;
    @Resource
    private IGmcRoleService roleServiceImpl;

    @Override
    public List<GmcUserRoleBO> queryUserRoleByUserId(Long userId) {
        List<UserRoleDO> userRoleDoS = userRoleMapper.selectList(new LambdaQueryWrapper<>(UserRoleDO.class).eq(UserRoleDO::getUserId, userId));
        if (Collections3.isEmpty(userRoleDoS)) {
            return Collections3.emptyList();
        }
        return JsonUtils.jsonToList(userRoleDoS, GmcUserRoleBO.class);
    }

    @Override
    public List<GmcUserRoleBO> queryUserRoleByRoleId(Long roleId) {
        List<UserRoleDO> userRoleDoS = userRoleMapper.selectList(new LambdaQueryWrapper<>(UserRoleDO.class).eq(UserRoleDO::getRoleId, roleId));
        if (Collections3.isEmpty(userRoleDoS)) {
            return Collections3.emptyList();
        }
        return JsonUtils.jsonToList(userRoleDoS, GmcUserRoleBO.class);
    }

    @Transactional(rollbackFor = {BusinessException.class})
    @Override
    public Boolean modifyUserRoleByUserId(CurrentUser currentUser, UserRoleParam userRoleParam) {
        Long administratorId = roleServiceImpl.selectAdministratorId();
        // 1. 查询现有角色权限关系
        List<UserRoleDO> haves = Optional
                .ofNullable(userRoleMapper.selectList(new LambdaQueryWrapper<>(UserRoleDO.class)
                        .eq(UserRoleDO::getUserId, userRoleParam.getUserId()))
                ).orElse(Collections3.emptyList());
        //查询当前操作人拥有的角色
        List<UserRoleDO> operators = Optional.ofNullable(userRoleMapper.selectList(new LambdaQueryWrapper<>(UserRoleDO.class).eq(UserRoleDO::getUserId, currentUser.getId()))).orElse(Collections3.emptyList());

        //过滤出可修改的权限
        List<Long> currentIds = Optional.ofNullable(Collections3.intersection(haves.parallelStream().map(UserRoleDO::getRoleId).collect(Collectors.toList()), operators.parallelStream().map(UserRoleDO::getRoleId).collect(Collectors.toList()))).orElse(Collections3.emptyList());
        if (null == userRoleParam.getRoleIds() || 0 == userRoleParam.getRoleIds().length) {
            if (Collections3.isEmpty(currentIds)) {
                return true;
            } else {
                return userRoleMapper.delete(new LambdaQueryWrapper<>(UserRoleDO.class).eq(UserRoleDO::getUserId, userRoleParam.getUserId()).in(UserRoleDO::getRoleId, currentIds)) > 0;
            }
        }
        List<Long> paramIds = Arrays.asList(userRoleParam.getRoleIds());
        List<Long> dels = new ArrayList<>();
        List<Long> saveIds = new ArrayList<>();
        if (!Collections3.isEmpty(currentIds)) {
            // 2。 进行取差集
            List<Long> difference = Collections3.difference(currentIds, paramIds);
            if (!Collections3.isEmpty(difference)) {
                dels.addAll(haves.parallelStream().filter(userRoleDO -> difference.contains(userRoleDO.getRoleId())).map(UserRoleDO::getId).collect(Collectors.toList()));
            }
            saveIds.addAll(Collections3.difference(paramIds, currentIds));
        } else {
            saveIds.addAll(paramIds);
        }

        // 删除不存在的关系
        if (!Collections3.isEmpty(dels)) {
            if (dels.contains(administratorId)) {
                throw new BusinessException("超级管理员至少要有1个用户");
            }
            userRoleMapper.deleteBatchIds(dels);
        }

        List<UserRoleDO> saves = new ArrayList<>();
        if (Collections3.isEmpty(saveIds)) {
            return true;
        } else {
            saveIds.parallelStream().forEach(key -> {
                UserRoleDO userRoleDO = new UserRoleDO();
                userRoleDO.setRoleId(key);
                userRoleDO.setUserId(userRoleParam.getUserId());
                userRoleDO.setDelStatus(0);
                saves.add(userRoleDO);
            });
        }
        // 新增关系
        userRoleMapper.insertBatchSomeColumn(saves);
        return true;
    }

    @Transactional(rollbackFor = {BusinessException.class})
    @Override
    public Boolean modifyUserRoleByRoleId(CurrentUser currentUser, RoleUserParam roleUserParam) {
        Boolean administrator = roleServiceImpl.checkIsAdministrator(Arrays.asList(roleUserParam.getRoleId()));
        if (administrator) {
            if (null == roleUserParam.getUserIds() || 0 == roleUserParam.getUserIds().length) {
                throw new BusinessException("超级管理员至少选择一个用户");
            } else if (roleUserParam.getUserIds().length > 1) {
                throw new BusinessException("超级管理员至多选择一个用户");
            }
        }

        // 1. 查询现有角色权限关系
        List<UserRoleDO> haves = Optional
                .ofNullable(userRoleMapper.selectList(new LambdaQueryWrapper<>(UserRoleDO.class)
                        .eq(UserRoleDO::getRoleId, roleUserParam.getRoleId()))
                ).orElse(Collections3.emptyList());
        //查询当前操作人拥有的用户
        List<UserRoleDO> userRoleDOS = userRoleMapper.selectList(new LambdaQueryWrapper<>(UserRoleDO.class).eq(UserRoleDO::getUserId, currentUser.getId()));
        List<Long> operators = Collections3.emptyList();
        if (!Collections3.isEmpty(userRoleDOS)) {
            List<UserRoleDO> userRoleDOS1 = userRoleMapper.selectList(new LambdaQueryWrapper<>(UserRoleDO.class)
                    .in(UserRoleDO::getRoleId, userRoleDOS.parallelStream().map(UserRoleDO::getRoleId).collect(Collectors.toList())));
            if (!Collections3.isEmpty(userRoleDOS)) {
                operators = userRoleDOS1.parallelStream().map(UserRoleDO::getUserId).collect(Collectors.toList());
            }
        }
        //过滤出可修改的权限
        List<Long> currentIds = Optional.ofNullable(Collections3.intersection(haves.parallelStream().map(UserRoleDO::getUserId).collect(Collectors.toList()), operators)).orElse(Collections3.emptyList());
        if (null == roleUserParam.getUserIds() || 0 == roleUserParam.getUserIds().length) {
            if (Collections3.isEmpty(currentIds)) {
                return true;
            } else {
                return userRoleMapper.delete(new LambdaQueryWrapper<>(UserRoleDO.class).eq(UserRoleDO::getRoleId, roleUserParam.getRoleId()).in(UserRoleDO::getUserId, currentIds)) > 0;
            }
        }
        List<Long> paramIds = Arrays.asList(roleUserParam.getUserIds());
        List<Long> dels = new ArrayList<>();
        List<Long> saveIds = new ArrayList<>();
        if (!Collections3.isEmpty(currentIds)) {
            // 2。 进行取差集
            List<Long> difference = Collections3.difference(currentIds, paramIds);
            if (!Collections3.isEmpty(difference)) {
                dels.addAll(haves.parallelStream().filter(userRoleDO -> difference.contains(userRoleDO.getUserId())).map(UserRoleDO::getId).collect(Collectors.toList()));
            }
            saveIds.addAll(Collections3.difference(paramIds, currentIds));
        } else {
            saveIds.addAll(paramIds);
        }

        // 删除不存在的关系
        if (!Collections3.isEmpty(dels)) {
            userRoleMapper.deleteBatchIds(dels);
        }

        List<UserRoleDO> saves = new ArrayList<>();
        if (Collections3.isEmpty(saveIds)) {
            return true;
        } else {
            saveIds.parallelStream().forEach(key -> {
                UserRoleDO userRoleDO = new UserRoleDO();
                userRoleDO.setRoleId(roleUserParam.getRoleId());
                userRoleDO.setUserId(key);
                userRoleDO.setDelStatus(0);
                saves.add(userRoleDO);
            });
        }
        // 新增关系
        userRoleMapper.insertBatchSomeColumn(saves);
        return true;
    }
}
